"""
生成测试数据的工具
用于生成测试和开发环境的样例数据
"""
import random
from datetime import datetime, timedelta
from faker import Faker
from app.extensions import db
from app.models.user import User, UserRole
from app.models.product import Product, ProductSpecification, ProductVariant, ProductStatus
from app.models.order import Order, OrderItem, OrderStatus, PaymentStatus
from app.models.logistics import LogisticsProvider, Logistics, TrackingNode, LogisticsStatus
from app.models.inventory import InventoryRecord, InventoryType

fake = Faker('zh_CN')

def create_fake_users(count=10):
    """创建测试用户"""
    users = []
    for i in range(count):
        user = User(
            username=fake.user_name(),
            email=fake.email(),
            full_name=fake.name(),
            role=random.choice([role.value for role in UserRole]),
            is_active=True
        )
        user.set_password('password123')
        users.append(user)
    
    db.session.add_all(users)
    db.session.commit()
    return users

def create_fake_products(count=20):
    """创建测试商品"""
    products = []
    for i in range(count):
        product = Product(
            name=fake.word() + '产品',
            description=fake.paragraph(),
            price=round(random.uniform(10, 1000), 2),
            stock=random.randint(10, 200),
            sku=f"SKU-{fake.random_number(digits=6)}",
            status=random.choice([status.value for status in ProductStatus])
        )
        products.append(product)
    
    db.session.add_all(products)
    db.session.commit()
    
    # 为每个商品添加规格和变体
    for product in products:
        # 添加规格
        color_spec = ProductSpecification(
            name='颜色',
            product=product
        )
        color_spec.option_list = ['红色', '蓝色', '黑色', '白色']
        
        size_spec = ProductSpecification(
            name='尺寸',
            product=product
        )
        size_spec.option_list = ['S', 'M', 'L', 'XL']
        
        db.session.add(color_spec)
        db.session.add(size_spec)
        
        # 添加变体
        for color in color_spec.option_list:
            for size in size_spec.option_list:
                variant = ProductVariant(
                    sku=f"{product.sku}-{color[0]}-{size}",
                    price=product.price + round(random.uniform(-10, 10), 2),
                    stock=random.randint(5, 50),
                    product=product
                )
                variant.specifications = {'颜色': color, '尺寸': size}
                db.session.add(variant)
    
    db.session.commit()
    return products

def create_fake_logistics_providers(count=5):
    """创建测试物流服务商"""
    providers = []
    for i in range(count):
        provider = LogisticsProvider(
            name=fake.company() + '物流',
            description=fake.paragraph(),
            website=fake.url(),
            contact=fake.phone_number(),
            is_active=True
        )
        providers.append(provider)
    
    db.session.add_all(providers)
    db.session.commit()
    return providers

def create_fake_orders(count=30, users=None, products=None, providers=None):
    """创建测试订单"""
    if not users:
        users = User.query.all()
    if not products:
        products = Product.query.all()
    if not providers:
        providers = LogisticsProvider.query.all()
    
    orders = []
    for i in range(count):
        user = random.choice(users)
        
        # 创建订单
        order = Order(
            order_number=f"ORD-{datetime.now().strftime('%Y%m%d%H%M%S')}-{i}",
            user=user,
            status=random.choice([status.value for status in OrderStatus]),
            total_amount=0,  # 稍后计算
            shipping_address=fake.address(),
            shipping_method=random.choice(['标准快递', '加急快递', '特快专递']),
            payment_method=random.choice(['支付宝', '微信支付', '银行转账']),
            payment_status=random.choice([status.value for status in PaymentStatus]),
            notes=fake.paragraph() if random.choice([True, False]) else None
        )
        
        # 添加订单项
        num_items = random.randint(1, 5)
        product_sample = random.sample(products, num_items)
        total_amount = 0
        
        for product in product_sample:
            # 随机选择一个变体
            variants = list(product.variants)
            if variants:
                variant = random.choice(variants)
                price = variant.price
                variant_id = variant.id
            else:
                price = product.price
                variant_id = None
            
            quantity = random.randint(1, 5)
            subtotal = price * quantity
            total_amount += subtotal
            
            order_item = OrderItem(
                order=order,
                product=product,
                variant_id=variant_id,
                quantity=quantity,
                price=price,
                subtotal=subtotal
            )
            db.session.add(order_item)
        
        order.total_amount = total_amount
        orders.append(order)
    
    db.session.add_all(orders)
    db.session.commit()
    
    # 为订单添加物流
    for order in orders:
        if order.status in [OrderStatus.SHIPPED.value, OrderStatus.DELIVERED.value, OrderStatus.COMPLETED.value]:
            provider = random.choice(providers)
            
            # 创建物流单
            logistics = Logistics(
                order=order,
                provider=provider,
                tracking_number=f"TRK-{fake.random_number(digits=10)}",
                status=random.choice([LogisticsStatus.SHIPPED.value, LogisticsStatus.IN_TRANSIT.value, LogisticsStatus.DELIVERED.value]),
                shipping_address=order.shipping_address,
                shipping_date=datetime.utcnow() - timedelta(days=random.randint(1, 5))
            )
            
            if logistics.status == LogisticsStatus.DELIVERED.value:
                logistics.delivery_date = datetime.utcnow() - timedelta(days=random.randint(0, 2))
            
            db.session.add(logistics)
            
            # 添加跟踪节点
            num_nodes = random.randint(1, 5)
            for j in range(num_nodes):
                node_status = random.choice([status.value for status in LogisticsStatus])
                node_date = logistics.shipping_date + timedelta(hours=j*12)
                
                tracking_node = TrackingNode(
                    logistics=logistics,
                    status=node_status,
                    location=fake.city(),
                    description=f"{node_status} in {fake.city()}",
                    timestamp=node_date
                )
                db.session.add(tracking_node)
    
    db.session.commit()
    return orders

def create_fake_inventory_records(count=100, products=None, users=None):
    """创建测试库存记录"""
    if not products:
        products = Product.query.all()
    if not users:
        users = User.query.all()
    
    records = []
    for i in range(count):
        product = random.choice(products)
        
        # 随机决定是使用产品还是变体
        if product.variants.count() > 0 and random.choice([True, False]):
            variant = random.choice(list(product.variants))
            product_id = product.id
            variant_id = variant.id
        else:
            product_id = product.id
            variant_id = None
        
        record_type = random.choice([type.value for type in InventoryType])
        
        # 根据类型设置数量
        if record_type in [InventoryType.OUT.value, InventoryType.RELEASE.value]:
            quantity = -random.randint(1, 10)
        else:
            quantity = random.randint(1, 20)
        
        record = InventoryRecord(
            product_id=product_id,
            variant_id=variant_id,
            type=record_type,
            quantity=quantity,
            balance=random.randint(10, 100),  # 模拟余量
            notes=fake.paragraph() if random.choice([True, False]) else None,
            operator_id=random.choice(users).id
        )
        records.append(record)
    
    db.session.add_all(records)
    db.session.commit()
    return records

def create_all_fake_data():
    """创建所有测试数据"""
    print("Creating fake users...")
    users = create_fake_users(20)
    
    print("Creating fake logistics providers...")
    providers = create_fake_logistics_providers(5)
    
    print("Creating fake products...")
    products = create_fake_products(30)
    
    print("Creating fake orders...")
    orders = create_fake_orders(50, users, products, providers)
    
    print("Creating fake inventory records...")
    records = create_fake_inventory_records(200, products, users)
    
    print("Fake data creation completed!")
    
    return {
        'users': users,
        'providers': providers,
        'products': products,
        'orders': orders,
        'records': records
    } 